package com.beta.auth.service.impl;

import com.alibaba.cloudapi.sdk.constant.SdkConstant;
import com.alibaba.cloudapi.sdk.enums.HttpMethod;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.beta.auth.config.UserAuthCfgBean;
import com.beta.auth.constants.AuthChannel;
import com.beta.auth.constants.BusinessConstants;
import com.beta.auth.dto.auth.AuthDto;
import com.beta.auth.dto.auth.GetUserInfoDto;
import com.beta.auth.dto.auth.WXAuthState;
import com.beta.auth.dto.saas.SaaSResponse;
import com.beta.auth.service.AbstractAuthService;
import com.beta.auth.service.SelfAppAuthService;
import com.beta.auth.utils.ResponseUtils;
import com.beta.auth.utils.SM4Helper2;
import com.beta.auth.utils.SaaSApiUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author gwqin
 * @description 本地和SAAS联合授权
 * @date 2023-07-13 17:25
 */
@Slf4j
@Service
public class BetaSaaSAuthServiceImpl extends AbstractAuthService {

    @Autowired
    private UserAuthCfgBean userAuthCfgBean;

    @Autowired
    private SelfAppAuthService selfAppAuthService;

    @Override
    public void invokeAuth(AuthDto authDto, WXAuthState authState, HttpServletRequest request, HttpServletResponse response) {
        try {
            // 1.校验参数合法性
            boolean result = super.checkAuthCode(authState, authDto, response);
            if(authDto.getAc() == -1) {
                return;
            }

            String redirectUrl;
            if (!result) {
                // 2.首次调用接口，构造企业微信授权链接
                redirectUrl = selfAppAuthService.getSelfAppAuthUrl(authState);
            } else {
                // 联合授权的本地授权部分是基础授权
                GetUserInfoDto dto = selfAppAuthService.getUserInfo(authDto.getCode(), false);

                if (Objects.isNull(dto) || StringUtils.isBlank(dto.getUserId())) {
                    log.warn("获取到用户基本信息为null，authDto = {}", JSON.toJSONString(authDto));
                    ResponseUtils.toErrPage(BusinessConstants.SYSTEM_ERROR_MSG, BusinessConstants.WX_ERROR_CODE, response);
                    return;
                }

                String userId = dto.getUserId();
                // 3.获取SAAS侧的授权链接
                redirectUrl = getSaasAuthUrl(userId, authState.getUstate(), authState.getReturnUrl(), authState.getExtAppId());
            }
            // 重定向到错误页面
            if (StringUtils.isBlank(redirectUrl)) {
                log.warn("联合授权，redirectUrl为空，authDto = {}", JSON.toJSONString(authDto));
                ResponseUtils.toErrPage(BusinessConstants.SYSTEM_ERROR_MSG, BusinessConstants.ALI_GATEWAY_ERROR_CODE,response);
                return;
            }

            // 4.重定向到授权地址进行授权
            ResponseUtils.sendRedirect(response, userAuthCfgBean.getSafeHosts(), redirectUrl);
        } catch (Exception e) {
            log.error("联合授权授权异常，异常信息：{}", e.getMessage(), e);
            ResponseUtils.toErrPage(BusinessConstants.SYSTEM_ERROR_MSG, BusinessConstants.UNKNOWN_ERROR_CODE, response);
        }
    }

    /**
     * 获取SAAS侧的授权链接地址
     *
     * @param userId
     * @param ustate
     * @param returnUrl
     * @param extAppId
     * @return
     */
    public String getSaasAuthUrl(String userId, String ustate, String returnUrl, String extAppId) {
        Map<String, String> queryParam = new HashMap<>();
        String extUserId = SM4Helper2.encryptSm4(userId.getBytes());
        queryParam.put("ExtUserId", extUserId);

        JSONObject body = new JSONObject(3);
        body.put("Ustate", ustate);
        body.put("ReturnUrl", returnUrl);
        body.put("ExtAppId", extAppId); // 渠道

        SaaSResponse response = SaaSApiUtil.requestSaaSApi(HttpMethod.POST_BODY, "/API/Gdxg/GetAuthUrl", queryParam, body.toJSONString().getBytes(SdkConstant.CLOUDAPI_ENCODING));
        if (!response.isSuccess()) {
            log.error("获取跳转链接失败 /API/Gdxg/GetAuthUrl，queryParam = {}，body = {}，saas返回信息 = {}", JSON.toJSONString(queryParam), JSON.toJSONString(body), JSON.toJSONString(response));
            return null;
        }

        JSONObject jsonObject = JSON.parseObject(response.getResponseBody());
        //判断调用saas端是否成功
        if (Objects.isNull(jsonObject)
                || jsonObject.isEmpty()
                || !jsonObject.getString("ErrorCode").equals("0000")
                || StringUtils.isEmpty(jsonObject.getString("Data"))) {
            log.error("获取跳转链接失败 /API/Gdxg/GetAuthUrl，queryParam = {}，body = {}，saas返回信息 = {}", JSON.toJSONString(queryParam), JSON.toJSONString(body), JSON.toJSONString(jsonObject));
            return null;
        }

        return jsonObject.getString("Data");
    }

    @Override
    public String getChannel() {
        return AuthChannel.BETA_SAAS.getChannel();
    }
}
